<template>
  <el-dialog
    v-model="dialogVisible"
    :title="file?.name"
    width="800px"
    fullscreen
    append-to-body
    destroy-on-close
  >
    <div class="preview-content">
      <!-- 图片预览 -->
      <div v-if="file?.type === 'image'" class="preview-image">
        <el-image 
          :src="file.path" 
          :preview-src-list="[file.path]"
          fit="contain"
        />
      </div>

      <!-- 视频预览 -->
      <div v-else-if="file?.type === 'video'" class="preview-video">
        <video 
          :src="file.path"
          controls
          autoplay
        />
      </div>

      <!-- 音频预览 -->
      <div v-else-if="file?.type === 'audio'" class="preview-audio">
        <audio 
          :src="file.path"
          controls
          autoplay
        />
      </div>

      <!-- PDF预览 -->
      <div v-else-if="file?.suffix === 'pdf'" class="preview-pdf">
        <iframe 
          :src="file.path"
          width="100%"
          height="100%"
        />
      </div>

      <!-- 其他文件 -->
      <div v-else class="preview-other">
        <el-empty description="该文件类型暂不支持预览" />
      </div>
    </div>

    <template #footer>
      <div class="preview-footer">
        <div class="file-info">
          <p>文件名：{{ file?.name }}</p>
          <p>大小：{{ formatFileSize(file?.size) }}</p>
          <p>类型：{{ getFileGroup(file?.suffix) }}</p>
          <p>更新时间：{{ file?.updateTime }}</p>
        </div>
        <div class="actions">
          <el-button @click="handleDownload">
            <el-icon><Download /></el-icon>下载
          </el-button>
        </div>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { Download } from '@element-plus/icons-vue'

interface FileInfo {
  name: string
  path: string
  size: number
  suffix: string
  type: string
  updateTime: string
}

const props = defineProps<{
  modelValue: boolean
  file?: FileInfo
}>()

const emit = defineEmits<{
  (e: 'update:modelValue', value: boolean): void
}>()

const dialogVisible = ref(props.modelValue)

watch(() => props.modelValue, (val) => {
  dialogVisible.value = val
})

watch(dialogVisible, (val) => {
  emit('update:modelValue', val)
})

// 文件类型配置
const FILE_TYPES = {
  image: { label: '图片' },
  document: { label: '文档' },
  video: { label: '视频' },
  audio: { label: '音频' },
  archive: { label: '压缩包' },
  code: { label: '代码' }
}

// 获取文件分组
const getFileGroup = (suffix?: string) => {
  if (!suffix) return '其他'
  suffix = suffix.toLowerCase()
  
  const typeMap: { [key: string]: string } = {
    'jpg,jpeg,png,gif,bmp,webp': 'image',
    'doc,docx,xls,xlsx,ppt,pptx,pdf,txt': 'document',
    'mp4,webm,ogg,mov,avi': 'video',
    'mp3,wav,ogg,aac': 'audio',
    'zip,rar,7z,tar,gz': 'archive',
    'js,ts,html,css,json,php,java,py,go,vue': 'code'
  }

  for (const [extensions, type] of Object.entries(typeMap)) {
    if (extensions.split(',').includes(suffix)) {
      return FILE_TYPES[type as keyof typeof FILE_TYPES].label
    }
  }
  return '其他'
}

// 文件下载
const handleDownload = () => {
  if (!props.file) return
  
  try {
    const link = document.createElement('a')
    link.href = props.file.path
    link.download = props.file.name
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
  } catch (error) {
    console.error('下载失败:', error)
    ElMessage.error('下载失败')
  }
}

// 工具函数
const formatFileSize = (size?: number) => {
  if (!size) return '0 B'
  if (size < 1024) return size + ' B'
  if (size < 1024 * 1024) return (size / 1024).toFixed(2) + ' KB'
  if (size < 1024 * 1024 * 1024) return (size / 1024 / 1024).toFixed(2) + ' MB'
  return (size / 1024 / 1024 / 1024).toFixed(2) + ' GB'
}
</script>

<style scoped lang="scss">
.preview-content {
  height: calc(100vh - 200px);
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: var(--el-bg-color-page);
  
  .preview-image,
  .preview-video,
  .preview-audio,
  .preview-pdf {
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    
    :deep(img),
    :deep(video),
    :deep(audio) {
      max-width: 100%;
      max-height: 100%;
      object-fit: contain;
    }
  }
}

.preview-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  
  .file-info {
    p {
      margin: $spacing-mini 0;
      color: var(--el-text-color-regular);
    }
  }
}
</style> 